<template>
	<div>
		<h1>双重加密和解密示例</h1>
		<input v-model="data.username" placeholder="输入用户名" /> <!-- 用户名输入框 -->
		<input v-model="data.password" placeholder="输入密码" /> <!-- 密码输入框 -->
		<button @click="encryptData">加密数据</button> <!-- 加密按钮 -->
		<button @click="decryptData">解密数据</button> <!-- 解密按钮 -->

		<p>加密结果: {{ encryptedResult }}</p> <!-- 显示加密结果 -->
		<p>解密结果: {{ decryptedResult }}</p> <!-- 显示解密结果 -->
	</div>
</template>

<script>
	import CryptoJS from 'crypto-js'; // 导入 CryptoJS 库用于加密和解密

	export default {
		data() {
			return {
				key: 'zzxxkj1729823908', // 与 Python 相同的密钥
				data: {
					acctID: '671ae6bf64998e', // 固定账户ID
					url: 'openapi.keyboardadmin.com:8888', // 固定URL
					username: '', // 用户输入的用户名
					password: '', // 用户输入的密码
				},
				encryptedResult: '', // 存储加密结果
				decryptedResult: '' // 存储解密结果
			};
		},
		methods: {

			// 生成随机字符串
			generateRandomString(n = 6) {
				const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // 可用字符集
				let randomString = ''; // 初始化随机字符串
				for (let i = 0; i < n; i++) {
					randomString += characters.charAt(Math.floor(Math.random() * characters.length)); // 随机选取字符
				}
				return randomString; // 返回生成的随机字符串
			},

			// AES-CBC 加密
			aesCbcEncrypt(data) {
				const iv = CryptoJS.lib.WordArray.random(16); // 生成随机初始化向量
				const ciphertext = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(this.key), {
					iv // 使用生成的 iv
				}).toString(); // 进行加密
				return {
					encryptedText: ciphertext, // 返回加密文本
					iv: iv.toString(CryptoJS.enc.Base64) // 返回 iv 的 Base64 编码
				};
			},

			// AES-CBC 解密
			aesCbcDecrypt(iv, ciphertext) {
				const decrypted = CryptoJS.AES.decrypt(ciphertext, CryptoJS.enc.Utf8.parse(this.key), {
					iv: CryptoJS.enc.Base64.parse(iv) // 使用 Base64 解码的 iv
				});
				return decrypted.toString(CryptoJS.enc.Utf8); // 返回解密后的文本
			},

			// 加密数据方法
			encryptData() {
				const dataString =
					`${this.data.acctID}|${this.data.url}|${this.data.username}|${this.data.password}`; // 组合待加密数据
				const extra = this.generateRandomString(6); // 生成随机字符串作为附加数据
				const start = Math.floor(Math.random() * 10); // 随机确定插入位置
				const plainText = dataString + extra; // 构造完整的明文

				const {
					encryptedText,
					iv
				} = this.aesCbcEncrypt(plainText); // 加密数据
				this.encryptedResult =
					`${encryptedText.slice(0, start)}${iv}${extra}${encryptedText.slice(start)}${start}`; // 拼接加密结果

				// 打印加密结果和相关信息
				console.log("加密结果:", this.encryptedResult); // 输出加密结果到控制台
				console.log("IV:", iv); // 打印 IV
				console.log("最初的密文:", encryptedText); // 打印最初的密文
				console.log("随机生成的 6 位字符串:", extra); // 打印随机生成的 6 位字符串
				this.decryptedResult = ''; // 清空解密结果
			},

			// 解密数据方法
			decryptData() {
				const start = parseInt(this.encryptedResult.slice(-1), 10); // 获取插入位置
				const iv = this.encryptedResult.slice(start, start + 24); // 提取 iv
				const extra = this.encryptedResult.slice(start + 24, start + 30); // 提取附加数据
				const ciphertext = this.encryptedResult.slice(0, start) + this.encryptedResult.slice(start + 30, -
					1); // 提取密文

				const decryptedText = this.aesCbcDecrypt(iv, ciphertext); // 解密


				// 检查解密结果是否以附加数据结尾
				if (decryptedText.endsWith(extra)) {
					const dataArray = decryptedText.slice(0, -6).split('|'); // 拆分解密后的数据
					this.decryptedResult = {
						acctID: dataArray[0],
						url: dataArray[1],
						username: dataArray[2],
						password: dataArray[3]
					}; // 构造解密后的数据对象
				} else {
					this.decryptedResult = '解密失败，数据不匹配！'; // 解密失败提示
				}

			}
		}
	};
</script>